package com.dubbo.service;

import com.dubbo.service.consumer.ConsumerService;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;


public class AnnotationConsumerMain {
    private static final Logger logger = LoggerFactory.getLogger(AnnotationConsumerMain.class);

    public static void main(String[] args) throws IOException, InterruptedException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class);
        context.start();
        ConsumerService service = context.getBean(ConsumerService.class);

        AtomicBoolean shoutDown = new AtomicBoolean(false);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(30, 30, 10, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>());

        execute(threadPoolExecutor, 10, shoutDown, new Callable() {
            @Override
            public Object call() throws Exception {
                return service.methodA();
            }
        });

        execute(threadPoolExecutor, 10, shoutDown, new Callable() {
            @Override
            public Object call() throws Exception {
                return service.methodB();
            }
        });

        execute(threadPoolExecutor, 10, shoutDown, new Callable() {
            @Override
            public Object call() throws Exception {
                return service.methodC();
            }
        });


        System.in.read();
        shoutDown.set(true);
        threadPoolExecutor.shutdown();
    }


    private static void execute(ThreadPoolExecutor threadPoolExecutor, int concurrentNum,AtomicBoolean shoutDown, Callable task){
        for (int i = 0; i < concurrentNum; i++) {
            threadPoolExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            if(shoutDown.get()){
                                return;
                            }
                            // long start = System.currentTimeMillis();
                            Object result = task.call();
                            // logger.info("result :" + result + ",耗时:" + (System.currentTimeMillis() - start));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        }
    }


    @Configuration
    @EnableDubbo
    @PropertySource("classpath:/dubbo-consumer.properties")
    @ComponentScan("com.dubbo.service")
    static class ConsumerConfiguration {

    }
}
